/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ClassDeclaration } from 'ts-morph';
import { ClassAnalysis, Logger } from '../../..';
import { DecoratorConstants } from '../../../constants';

/**
 * 合并版Sendable类生成器
 *
 * 当满足合并条件时，将原始类直接转换为Sendable类：
 * - 移除所有TurboTrans装饰器 (@Serializable, @SerialName, @Required, @Transient)
 * - 添加 @Sendable 装饰器
 * - 类名保持不变
 * - 添加 ITSerializable 接口和相关方法
 */
export class MergedSendableClassGenerator {
  // TurboTrans装饰器集合
  private static readonly TURBO_TRANS_DECORATORS = new Set(DecoratorConstants.SERIAL_DECORATORS);

  generate(classDecl: ClassDeclaration, classAnalysis: ClassAnalysis): void {
    // 1. 移除TurboTrans装饰器
    this.removeTurboTransDecorators(classDecl);

    // 2. 添加@Sendable装饰器
    this.addSendableDecorator(classDecl);

    // 3. 添加ITSerializable接口
    this.addITSerializableInterface(classDecl);

    // 4. 生成三个核心方法
    this.generateConvertToSendableMethod(classDecl, classAnalysis); // 返回自身
    this.generateToOriginMethod(classDecl, classAnalysis);
    this.generateToJsonMethod(classDecl, classAnalysis);

    Logger.debug(`成功生成合并版Sendable类: ${classAnalysis.className}`);
  }

  private removeTurboTransDecorators(classDecl: ClassDeclaration): void {
    // 移除类级别的TurboTrans装饰器
    const classDecorators = classDecl.getDecorators();
    classDecorators.forEach(decorator => {
      const decoratorName = decorator.getName();
      if (MergedSendableClassGenerator.TURBO_TRANS_DECORATORS.has(decoratorName)) {
        decorator.remove();
        Logger.debug(`移除类 ${classDecl.getName()} 的装饰器: @${decoratorName}`);
      }
    });

    // 移除属性级别的TurboTrans装饰器
    const properties = classDecl.getProperties();
    properties.forEach(property => {
      const propDecorators = property.getDecorators();
      propDecorators.forEach(decorator => {
        const decoratorName = decorator.getName();
        if (MergedSendableClassGenerator.TURBO_TRANS_DECORATORS.has(decoratorName)) {
          decorator.remove();
          Logger.debug(`移除属性 ${property.getName()} 的装饰器: @${decoratorName}`);
        }
      });
    });
  }

  private addSendableDecorator(classDecl: ClassDeclaration): void {
    classDecl.addDecorator({ name: 'Sendable' });
  }

  private addITSerializableInterface(classDecl: ClassDeclaration): void {
    // 检查是否已经实现了接口
    const existingImplements = classDecl.getImplements().map(impl => impl.getText());
    if (existingImplements.some(impl => impl.includes('ITSerializable'))) {
      Logger.warn(`类 ${classDecl.getName()} 已经实现了ITSerializable接口, 跳过接口添加`);
      return;
    }

    // 添加接口实现
    classDecl.addImplements(['ITSerializable', 'lang.ISendable']);
  }

  /**
   * 生成toSendable方法
   * 对于合并版Sendable类，直接返回自身（因为类本身已经是Sendable）
   */
  private generateConvertToSendableMethod(classDecl: ClassDeclaration, classAnalysis: ClassAnalysis): void {
    // 检查是否已存在该方法
    if (classDecl.getMethod('toSendable')) {
      Logger.warn(`类 ${classAnalysis.className} 已存在toSendable方法，跳过生成`);
      return;
    }

    // 合并版Sendable类的toSendable方法返回自身
    let returnType = classAnalysis.className;
    if (classAnalysis.generics.parameters.length > 0) {
      returnType += `<${classAnalysis.generics.parameters.join(', ')}>`;
    }

    classDecl.addMethod({
      name: 'toSendable',
      returnType: returnType,
      statements: ['return this;'] // 直接返回自身
    });

    Logger.debug(`为合并版Sendable类 ${classAnalysis.className} 生成toSendable方法（返回自身）`);
  }

  private generateToOriginMethod(classDecl: ClassDeclaration, classAnalysis: ClassAnalysis): void {
    // 检查是否已存在该方法
    if (classDecl.getMethod('toOrigin')) {
      Logger.warn(`类 ${classAnalysis.className} 已存在toOrigin方法，跳过生成`);
      return;
    }

    // 合并版Sendable类的toSendable方法返回自身
    let returnType = classAnalysis.className;
    if (classAnalysis.generics.parameters.length > 0) {
      returnType += `<${classAnalysis.generics.parameters.join(', ')}>`;
    }

    classDecl.addMethod({
      name: 'toOrigin',
      returnType: returnType,
      statements: ['return this;'] // 直接返回自身
    });

    Logger.debug(`为合并版Sendable类 ${classAnalysis.className} 生成toOrigin方法（返回自身）`);
  }

  private generateToJsonMethod(classDecl: ClassDeclaration, classAnalysis: ClassAnalysis): void {
    // 检查是否已存在该方法
    if (classDecl.getMethod('toJson')) {
      Logger.warn(`类 ${classAnalysis.className} 已存在toJson方法，跳过生成`);
      return;
    }

    const methodBody = 'return TJSON.toString(this, typeKey)';

    classDecl.addMethod({
      name: 'toJson',
      returnType: 'string',
      parameters: [{
        name: 'typeKey',
        type: 'TypeKey',
        hasQuestionToken: true
      }],
      statements: [methodBody]
    });
  }
}
